home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacWT 0.9 / wt Mac Source / pictrload.c < prev    next >
Encoding:
Text File  |  1995-10-23  |  8.8 KB  |  414 lines  |  [TEXT/CWIE]

  1. /*
  2. **  MacWT -- a 3d game engine for the Macintosh
  3. **  © 1995, Bill Hayden and Nikol Software
  4. **  Free for non-commercial use - address questions to the e-mail address below
  5. **
  6. **  Mail:           afn28988@freenet.ufl.edu (Bill Hayden)
  7. **    MacWT FTP site: ftp.circa.ufl.edu/pub/software/ufmug/mirrors/LocalSW/Hayden/
  8. **  WWW Page:       http://grove.ufl.edu:80/~nikolsw
  9. **
  10. **    All of the above addresses are due to changes sometime in 1996, so stay tuned
  11. **
  12. **  based on wt, by Chris Laurel
  13. **
  14. **  This program is distributed in the hope that it will be useful,
  15. **  but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. */
  18.  
  19. // Modifications by EDAN SHALEV (edan@netcom.com) 9/26/95
  20.  
  21. #include <stdlib.h>
  22. #include <stdio.h>
  23. #include "wt.h"
  24. #include "error.h"
  25. #include "wtmem.h"
  26. #include "color.h"
  27. #include "graphfile.h"
  28. #include "StringUtils.h"
  29.  
  30.  
  31. static PicHandle PictFromFile(short fref);
  32. static OSErr CreateCGrafPortFromPict(CGrafPtr *newCGrafPort, PicHandle srcPictH);
  33. static OSErr SetUpPixMap(PixMapHandle aPixMap, short depth, Rect *bounds, CTabHandle colors, short bytesPerRow);
  34. static OSErr CreateCGrafPort(CGrafPtr *newCGrafPort, Rect *bounds, short depth, CTabHandle colors, GDHandle useGDevice);
  35. static OSErr CreateBestCGrafPort(CGrafPtr *tempCGrafPort, Rect *bounds);
  36.  
  37.  
  38.  
  39. /*****************************************************************************/
  40.  
  41.  
  42.  
  43. Graphic_file *LoadPICTR(FILE *fp, char *filename)
  44. {
  45.     Graphic_file    *gfile = nil;
  46.     PicHandle        hPic;
  47.     RGBColor        thePixel;
  48.     long            index = 0;
  49.     short            h, v;
  50.     GrafPtr            savePort;
  51.     short            vref, HomeRes, fref;
  52.     OSErr            err = noErr;
  53.     CGrafPtr         saveCPort;
  54.  
  55.     
  56.  
  57.     HomeRes = CurResFile();
  58.     
  59.     err = GetVol(nil, &vref);
  60.     c2p(filename);
  61.     fref = OpenResFile( (StringPtr)filename );
  62.  
  63.     if (err || fref == -1)
  64.         {
  65.         p2c((StringPtr)filename);
  66.         return gfile;
  67.         }
  68.  
  69.     
  70.     UseResFile( fref );
  71.     
  72.     if (Count1Resources( 'PICT' ))
  73.         {
  74.         hPic = (PicHandle)Get1IndResource( 'PICT', 1 );
  75.         vref = -1;
  76.         }
  77.     else
  78.         {
  79.         err = FSClose( fref );
  80.         
  81.         err = OpenDF( (StringPtr)filename, vref, &fref );
  82.         hPic = PictFromFile(fref);
  83.         err = FSClose (fref);
  84.         }
  85.         
  86.     if (hPic)
  87.         {        
  88.         gfile = new_graphic_file();
  89.         gfile->type = gfTrueColor;
  90.         gfile->palette = NULL;
  91.         gfile->width = (*hPic)->picFrame.right - (*hPic)->picFrame.left;
  92.         gfile->height = (*hPic)->picFrame.bottom - (*hPic)->picFrame.top;
  93.         gfile->bitmap = (unsigned char *)wtmalloc(gfile->height * gfile->width * 3);
  94.         
  95.         GetPort(&savePort);
  96.         err = CreateCGrafPortFromPict( &saveCPort, hPic);
  97.         SetPort((GrafPtr)saveCPort);
  98.         
  99.         // I think there is a better (quicker) way to do this, but I'll have to check
  100.         
  101.         for (v = 0; v < (gfile->height); v++)
  102.             for (h = 0; h < (gfile->width); h++)
  103.                 {
  104.                 GetCPixel(h, v, &thePixel);
  105.                 gfile->bitmap[index++] = (unsigned char)(thePixel.red >> 8);
  106.                 gfile->bitmap[index++] = (unsigned char)(thePixel.green >> 8);
  107.                 gfile->bitmap[index++] = (unsigned char)(thePixel.blue >> 8);
  108.                 }
  109.         
  110.         SetPort(savePort);
  111.         CloseCPort(saveCPort);
  112.         DisposePtr((Ptr)saveCPort);
  113.  
  114.         
  115.         if (vref == -1)
  116.             ReleaseResource((Handle)hPic);
  117.         else
  118.             DisposeHandle((Handle)hPic);
  119.         }
  120.  
  121.     UseResFile(HomeRes);
  122.     
  123.     p2c((StringPtr)filename);
  124.     
  125.     return gfile;
  126. }
  127.  
  128.  
  129.  
  130.  
  131. static PicHandle PictFromFile(short fref)
  132. {
  133.     PicHandle    thePic;
  134.     const short kPictHeaderSize = 512;    // Length of PICT header in bytes
  135.     long        pictFileLen;            // Length of the PICT file
  136.     OSErr        err;
  137.     
  138.     
  139.     err = GetEOF(fref, &pictFileLen);
  140.  
  141.         // Skip over the 512 byte header which we don't need
  142.     err = SetFPos(fref, fsFromStart, kPictHeaderSize);
  143.  
  144.         // Adjust the length of the pict file (shorten by 512) to
  145.         // account for our skipping the first 512 bytes
  146.     pictFileLen -= kPictHeaderSize;
  147.         
  148.     if (pictFileLen <= 0)
  149.         return nil;
  150.         
  151.         // Now, allocate some memory with which to load our pict file in.
  152.     thePic = (PicHandle)NewHandleClear(pictFileLen);
  153.     if (thePic == nil)
  154.         return(nil);
  155.  
  156.         // Lock the buffer
  157.     HLock((Handle)thePic);
  158.  
  159.         // Okay, read in the pict file
  160.     err = FSRead(fref, &pictFileLen, (Ptr)*thePic);
  161.     
  162.     HUnlock((Handle)thePic);
  163.     
  164.     return(thePic);    
  165. }
  166.  
  167.  
  168.  
  169.  
  170.  
  171. static OSErr CreateCGrafPortFromPict( CGrafPtr *newCGrafPort, PicHandle srcPictH)
  172. {
  173.     OSErr             err;
  174.     GrafPtr            savePort;
  175.     CGrafPtr         tempCGrafPort;
  176.     Rect             pictRect;
  177.  
  178.     *newCGrafPort = NULL;
  179.  
  180.     GetPort(&savePort);
  181.  
  182.     pictRect.left = 0;
  183.     pictRect.top = 0;
  184.     pictRect.right = (**srcPictH).picFrame.right - (**srcPictH).picFrame.left;
  185.     pictRect.bottom = (**srcPictH).picFrame.bottom - (**srcPictH).picFrame.top;
  186.  
  187.     err = CreateBestCGrafPort(&tempCGrafPort, &pictRect);
  188.  
  189.     if (err == noErr)
  190.         {
  191.         SetPort((GrafPtr)tempCGrafPort);
  192.  
  193.         DrawPicture(srcPictH, &pictRect);
  194.  
  195.         *newCGrafPort = tempCGrafPort;
  196.         }
  197.  
  198.     SetPort(savePort);
  199.  
  200.     return err;
  201. }
  202.  
  203. static OSErr CreateBestCGrafPort( CGrafPtr *newCGrafPort, Rect    *offScreenRect)            
  204. {
  205.     OSErr                err = noErr;                    
  206.     GDHandle            baseGDevice;            
  207.     PixMapHandle        basePixMap;                
  208.     Rect                tempOffScreenRect;        
  209.  
  210.  
  211.     baseGDevice = GetMaxDevice(offScreenRect);
  212.  
  213.     if ((baseGDevice != NULL) && (err == noErr))
  214.         {
  215.         tempOffScreenRect = *offScreenRect;
  216.         OffsetRect(&tempOffScreenRect, -tempOffScreenRect.left, -tempOffScreenRect.top);
  217.         basePixMap = (**baseGDevice).gdPMap;
  218.         err = CreateCGrafPort(newCGrafPort, &tempOffScreenRect, (**basePixMap).pixelSize,
  219.                                 (**basePixMap).pmTable, baseGDevice);
  220.         }
  221.  
  222.     return err;
  223. }
  224.  
  225.  
  226.  
  227. #define kMaxRowBytes 0x3FFE                 
  228.  
  229. static OSErr CreateCGrafPort(
  230.     CGrafPtr        *newCGrafPort,            
  231.     Rect            *bounds,                
  232.     short            depth,                    
  233.     CTabHandle        colors,                        
  234.     GDHandle        useGDevice)                
  235. {
  236.     CGrafPtr            tempCGrafPort;        
  237.     PixMapHandle        newPixMap;            
  238.     GDHandle            newDevice;            
  239.     long                qdVersion;            
  240.     GrafPtr                savedPort;            
  241.     SignedByte            savedState;            
  242.     short                bytesPerRow;        
  243.     OSErr                err;                
  244.  
  245.         
  246.     tempCGrafPort = NULL;
  247.     newPixMap = NULL;
  248.     newDevice = NULL;
  249.     err = noErr;
  250.  
  251.         
  252.     if (colors != NULL)
  253.         {
  254.         savedState = HGetState( (Handle)colors );
  255.         HNoPurge( (Handle)colors );
  256.         }
  257.  
  258.     bytesPerRow = ((depth * (bounds->right - bounds->left) + 31) >> 5) << 2;
  259.     err = Gestalt(gestaltQuickdrawVersion, &qdVersion);
  260.  
  261.     if (err == noErr)
  262.     {
  263.             
  264.         if (depth == 1 || depth == 2 || depth == 4 || depth == 8 ||
  265.             ((depth == 16 || depth == 32) && qdVersion >= gestalt32BitQD))
  266.         {
  267.             if (bytesPerRow <= kMaxRowBytes)
  268.             {
  269.                 if (depth <= 8)
  270.                     if (colors == NULL)
  271.                         err = paramErr;
  272.                 }
  273.             else
  274.                 err = paramErr;
  275.         }
  276.         else
  277.             err = paramErr;
  278.     }
  279.  
  280.     if (err == noErr)
  281.         {
  282.         tempCGrafPort = (CGrafPtr)NewPtr(sizeof (CGrafPort) );
  283.         if (tempCGrafPort != NULL)
  284.             {
  285.             GetPort( &savedPort );
  286.             OpenCPort( tempCGrafPort );
  287.             tempCGrafPort->portRect = *bounds;
  288.             RectRgn( tempCGrafPort->visRgn, bounds );
  289.             ClipRect( bounds );
  290.  
  291.             err = SetUpPixMap(tempCGrafPort->portPixMap, depth, bounds, colors, bytesPerRow);
  292.  
  293.             if (err == noErr)
  294.                 {
  295.                 EraseRect(bounds);
  296.  
  297.                 newPixMap = tempCGrafPort->portPixMap;
  298.                 }
  299.             SetPort(savedPort);
  300.             }
  301.         else
  302.             err = MemError();
  303.         }
  304.  
  305.     if (colors != NULL)
  306.         HSetState((Handle)colors, savedState);
  307.  
  308.     if (err != noErr)
  309.         {
  310.         if (newPixMap != NULL)
  311.             {
  312.             DisposeCTable((**newPixMap).pmTable);
  313.             DisposePtr((**newPixMap).baseAddr);
  314.             }
  315.  
  316.         if (tempCGrafPort != NULL)
  317.             {
  318.             CloseCPort(tempCGrafPort);
  319.             DisposePtr((Ptr)tempCGrafPort);
  320.             }
  321.         }
  322.     else
  323.         {
  324.         *newCGrafPort = tempCGrafPort;
  325.         }
  326.  
  327.     return err;
  328. }
  329.  
  330.  
  331.  
  332.  
  333. #define kDefaultRes 0x00480000
  334.  
  335. static OSErr SetUpPixMap(
  336.     PixMapHandle        aPixMap,        
  337.     short                depth,            
  338.     Rect                *bounds,        
  339.     CTabHandle            colors,            
  340.     short                bytesPerRow)    
  341. {
  342.     CTabHandle    newColors;                
  343.     Ptr            offBaseAddr;            
  344.     OSErr        err;                
  345.  
  346.     err = noErr;
  347.     newColors = NULL;
  348.     offBaseAddr = NULL;
  349.  
  350.     if (depth <= 8)
  351.         {
  352.         newColors = colors;
  353.         err = HandToHand( (Handle *)&newColors );
  354.         }
  355.     else
  356.         {
  357.         newColors = (CTabHandle)NewHandle(sizeof(ColorTable) - sizeof(CSpecArray));
  358.         err = MemError();
  359.         }
  360.  
  361.     if (err == noErr)
  362.         {
  363.         offBaseAddr = NewPtr((Size)bytesPerRow *
  364.                                 (bounds->bottom - bounds->top) );
  365.         if (offBaseAddr != NULL)
  366.             {    
  367.             (**aPixMap).baseAddr = offBaseAddr;
  368.             (**aPixMap).rowBytes = bytesPerRow | 0x8000;
  369.             (**aPixMap).bounds = *bounds;        
  370.             (**aPixMap).pmVersion = 0;               
  371.             (**aPixMap).packType = 0;            
  372.             (**aPixMap).packSize = 0;            
  373.             (**aPixMap).hRes = kDefaultRes;          
  374.             (**aPixMap).vRes = kDefaultRes;          
  375.             (**aPixMap).pixelSize = depth;           
  376.             (**aPixMap).planeBytes = 0;              
  377.             (**aPixMap).pmReserved = 0;              
  378.  
  379.             if (depth <= 8)
  380.                 {
  381.                 (**aPixMap).pixelType = 0;            
  382.                 (**aPixMap).cmpCount = 1;            
  383.                 (**aPixMap).cmpSize = depth;        
  384.                 (**aPixMap).pmTable = newColors;    
  385.                 }
  386.             else
  387.                 {
  388.                 (**aPixMap).pixelType = RGBDirect;        
  389.                 (**aPixMap).cmpCount = 3;                
  390.                 if (depth == 16)
  391.                     (**aPixMap).cmpSize = 5;            
  392.                 else
  393.                     (**aPixMap).cmpSize = 8;            
  394.                 (**newColors).ctSeed = 3 * (**aPixMap).cmpSize;
  395.                 (**newColors).ctFlags = 0;
  396.                 (**newColors).ctSize = 0;
  397.                 (**aPixMap).pmTable = newColors;
  398.                 }
  399.             }
  400.         else
  401.             err = MemError();
  402.         }
  403.     else
  404.         newColors = NULL;
  405.  
  406.     if (err != noErr)
  407.         {
  408.         if (newColors != NULL)
  409.             DisposeCTable( newColors );
  410.         }
  411.     
  412.     return err;
  413. }
  414.